/**
 * 
 */
package org.swing.utility.common.chars;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * @author lqnhu
 *
 */
public class ByteArrayReadOnlyUtfBuf extends AbstractReadOnlyUtfBuf {
	protected final byte[] data;

	public ByteArrayReadOnlyUtfBuf(byte[] data) {
		if (data == null) {
			throw new NullPointerException("data");
		}
		this.data = data;
	}

	// ideally only used for low-performance requirement code; like testing
	public ByteArrayReadOnlyUtfBuf(String javaString) {
		if (javaString == null) {
			throw new NullPointerException("java string");
		}
		this.data = javaString.getBytes(StandardCharsets.UTF_8);
	}

	
	public byte getByte(int index) {
		return data[index];
	}

	
	public int getByteLength() {
		return data.length;
	}

	
	public ReadableCharBuf getSubSequenceForByteBounds(int start, int end) {
		// TODO: reconsider support byte[] slices; was ignored previously under
		// the expectation
		// that slices are already handled by ByteBufs, but ByteBufs are less
		// immediately performant
		// than we might have hoped.
		int length = end - start;
		byte[] wastefulClone = new byte[length];
		System.arraycopy(data, start, wastefulClone, 0, length);
		return new ByteArrayReadOnlyUtfBuf(wastefulClone);
	}

	
	public ByteBuf toByteBuf() {
		return Unpooled.wrappedBuffer(data);
	}

	
	public String toString() {
		if (knownAsciiOnly(packedIndexCache)) {
			return new String(data, 0);
		} else {
			return new String(data, StandardCharsets.UTF_8);
		}
	}

	
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}
		if (obj instanceof ByteArrayReadOnlyUtfBuf) {
			return Arrays.equals(data, ((ByteArrayReadOnlyUtfBuf) obj).data);
		} else if (obj instanceof ReadableCharBuf) {
			return ByteBufUtil.equals(((ReadableCharBuf) obj).toByteBuf(),
					toByteBuf());
		}
		return false;
	}
}